package cn.skyquant.quant4j.sdk.util.bean;

import cn.skyquant.quant4j.sdk.util.constant.SystemConstants;
import cn.skyquant.quant4j.sdk.util.log.LogUtil;
import com.google.common.collect.Maps;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class BeanTools {

    private static final Map<String,List<EnumEntity>> cacheEnumFields = Maps.newHashMap();

    public static List<EnumEntity> getEnumFields(String className){
        if(cacheEnumFields.containsKey(className)){
            return cacheEnumFields.get(className);
        }
        try {
            Class clazz = Class.forName(className);
            if(clazz!=null && clazz.isEnum() ){
                Method method = clazz.getMethod("values");
                if(method!=null){
                    Object object = method.invoke(null);
                    if(object instanceof Enum[]){
                        Enum[] enums = (Enum[]) object;
                        List<EnumEntity> list = new ArrayList<>();
                        for(int i=0;enums!=null && i<enums.length;i++){
                            list.add( new EnumEntity(enums[i].name(),enums[i].toString()));
                        }
                        cacheEnumFields.put(className,list);
                        return list;
                    }
                }
            }
        } catch (Exception e) {
            LogUtil.error("getEnumFields error:"+className,e);
        }
        return SystemConstants.emptyList;
    }

    /**
     * 只复制public 同名同类型的字段
     * @param source 源对象
     * @param target 目标对象
     */
    public static void copyPublicFields(Object source,Object target){
        if(source==null||target==null){
            return;
        }
        Class c1 = source.getClass();
        Class c2 = target.getClass();
        Field[] f1s = c1.getFields();
        Field[] f2s = c2.getFields();
        for(Field f1:f1s){
            Object value = null;
            try {
                value = f1.get(source);
            } catch (IllegalAccessException e) {
                continue;
            }
            //不copy空字段
            if(value==null){
                continue;
            }
            //不copy集合类型
            if(value instanceof Iterable){
                continue;
            }
            //不copy静态类型
            if(Modifier.isStatic(f1.getModifiers())){
                continue;
            }
            for(Field f2:f2s){
                if(!Modifier.isStatic(f2.getModifiers())
                        && f1.getType() == f2.getType()             //类型相同
                        && f1.getName().equals(f2.getName())){      //名称相等
                    //反射赋值
                    try {
                        f2.set(target,value);
                    } catch (IllegalAccessException e) {

                    }
                    break;
                }
            }
        }
    }
}
